package com.asen.commons.context;

import com.asen.commons.concurrent.ThreadLocalCache;
import com.asen.commons.utils.BaseAssert;
import com.asen.commons.utils.HttpRequestUtil;
import com.asen.commons.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * 请求会话容器
 *
 * @author Gary
 * @version 1.0
 * @date 2020-04-22
 */
@Slf4j
public class ContextHolder {

    public static Map<String, Object> getAll() {
        return ThreadLocalCache.getAll();
    }

    public static Object get(String key) {
        return ThreadLocalCache.get(key);
    }

    public static void put(String key, Object value) {
        ThreadLocalCache.put(key, value);
    }

    public static void remove(String key) {
        ThreadLocalCache.remove(key);
    }

    public static String getString(String key) {
        Object value = get(key);
        return value == null ? null : value.toString();
    }

    /**
     * 获取租户ID
     *
     * @return
     */
    public static Long getTenantId() {
        Long tenantId = ThreadLocalCache.getTenantId();
        if (tenantId == null) {
            tenantId = HttpRequestUtil.getTenantIdFromRequest();
            if (tenantId == null) {
                // TODO
                //tenantId = LoginUtils.getLoginTenantId();
            }
            ThreadLocalCache.setTenantId(tenantId);
        }
        return tenantId;
    }

    public static String getStringTenantId() {
        Long tenantId = getTenantId();
        return tenantId == null ? null : tenantId.toString();
    }

    public static void setTenantId(Long tenantId) {
        ThreadLocalCache.setTenantId(tenantId);
    }

    /**
     * 不包含前缀Authorization
     *
     * @return
     */
    public static String getAuthToken() {
        String authToken = ThreadLocalCache.getAuthToken();
        if (StringUtils.isBlank(authToken)) {
            authToken = HttpRequestUtil.getTokenFromRequest(true);
            ThreadLocalCache.setAuthToken(authToken);
        }
        return authToken;
    }

    /**
     * 不包含前缀Authorization
     *
     * @return
     */
    public static void setAuthToken(String token) {
        ThreadLocalCache.setAuthToken(token);
    }

    public static void changeDataSource(Long tenantId) {
        BaseAssert.notNull(tenantId, "租户ID不能为空！");
        String dsId = "ds_".concat(tenantId.toString());
        // TODO
        //String msg = "数据源[" + dsId + "]不存在，请联系管理员！";
        //BaseAssert.check(DynamicDataSourceContextHolder.containsDataSource(dsId), msg);

        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        StringBuilder sb = new StringBuilder();
        if (stackTrace.length >= 3) {
            String[] packages = new String[]{"com.abel", "com.cis", "com.dachuangtech"};
            for (int i = 2; i < stackTrace.length; i++) {
                if (!StringUtils.startsWithAny(stackTrace[i].getClassName(), packages)) {
                    break;
                }
                sb.append(sb.length() > 0 ? " > " : "");
                sb.append(stackTrace[i].getMethodName());
                sb.append(" - (");
                sb.append(stackTrace[i].getFileName());
                sb.append(":");
                sb.append(stackTrace[i].getLineNumber());
                sb.append(")");
            }
        }

        log.info("Changing DataSource : {} > {}", dsId, sb.toString());
        ContextHolder.setTenantId(tenantId);
        // TODO
        //DynamicDataSourceContextHolder.setDataSourceType(dsId);
    }

    public static void clear() {
        ThreadLocalCache.clear();
    }
}
